package SecondeStage.MianXiangDuiXiang.AbstractClass.CodeBlock;

public class CodeBlockDetils {
    public static void main(String[] args) {
        // 创建一个对象时，在一个类调用顺序是：
        // ① 调用静态代码块和静态属性初始化（二者的优先级一样，如果有多个静态代码块和静态属性初始化，则按定义顺序执行）
        // ② 调用普通代码块和普通属性初始化（二者的优先级一样，如果有多个普通代码块和普通属性初始化，则按定义顺序执行）
        // ③ 调用构造方法
        //A a =new A();
        System.out.println("--------------------------");
        // 创建一个子类对象时，调用顺序如下:
        // ① 父类的静态代码块和静态属性初始化
        // ② 子类的静态代码块和静态属性
        // ③ 父类的普通代码块和普通属性初始化
        // ④ 父类的构造方法
        // ⑤ 子类的普通代码块和普通属性初始化
        // ⑥ 子类的构造方法
        new B();

        // 静态代码块只能调用静态成员，普通代码块能调用任意成员
    }
}

class A{
    private static int n1=getN1();
    private int n2 = getN2();

    public A() {
        // 1. super()
        // 2. 调用本类的普通代码块
        System.out.println("A的构造器被调用...");
    }

    static {
        System.out.println("A 静态代码块01");
    }

    {
        System.out.println("A 普通代码块02");
    }

    public static  int getN1(){
        System.out.println("getN1()被调用...");
        return n1;
    }

    public int getN2(){
        System.out.println("getN2()被调用...");
        return n2;
    }
}

class B extends A{

    {
        System.out.println("B的普通代码块被调用...");
    }

    public B() {
        // 构造器实际上隐藏调用的有以下两行代码
        // 1. super()
        // 2. 调用本类的普通代码块
        System.out.println("B的构造器被调用...");
    }
}
